package com.gitee.wsl.ext.map

import arrow.core.getOrNone
import com.gitee.wsl.base.Option


fun <K> MutableMap<K, Int>.increment(key: K) {
    this.getOrPut(key) { 0 }
    this[key] = this[key]!! + 1
}

/**
 * Utility function to either [MutableMap.remove] or [MutableMap.put] a [key]/[value] from a [MutableMap]
 * depending on the nullability of the value.
 */
fun <K, V> MutableMap<K, V>.putOrRemove(key: K, value: V?) {
    if (value == null) {
        this.remove(key)
    } else {
        this[key] = value
    }
}

/**
 * Replaces all of the elements of this [MutableMap] with the elements of the provided map.
 */
fun <K, V> MutableMap<K, V>.setAll(other: Map<K, V>) {
    clear()
    other.forEach { (key, value) -> set(key, value) }
}

inline fun <K, V> HashMap<K, MutableList<V>>.updateList(
    key: K,
    initialCapacity: Int = 0,
    block: MutableList<V>.() -> Unit,
) {
    block(getOrPut(key) { ArrayList(initialCapacity) })
}


fun <K, V,T,R> Map<K, V>.tran( block : (Map.Entry<K,V>) -> Pair<T,R> ) = map { block(it) }.toMap()


/**
 * Extension function to get an Option from a nullable object on a map.
 */
fun <K, A> Map<K, A>.getOption(k: K): Option<A> =
    getOrNone(k)
